package ws.very.util.akka.cluster

import ws.very.util.akka.util.AkkaSystemable
import akka.actor._
import akka.cluster._
import akka.cluster.ClusterEvent._
import akka.cluster.MemberStatus._
@deprecated
trait IClusterStates {
  def upMembers: Set[Member] //Up状态的机器  
  def downMembers: Set[Member] //已经被removed的机器
  def exitedMembers: Set[Member] //提出集群的机器，集群访问无效但是Rmi和远程akka可以访问
  def unreachableMembers: Set[Member] //心跳信号访问不到的机器，可能因为网络不稳而暂时访问不到
  def roleLeaderMemberMap: Map[String, Option[Address]] //哪些角色
  def leaderMember: Option[Address]
  def nodeMemberMetrics: Set[NodeMetrics]
  def seenByMembers: Set[Address] //被哪几台监视
  def init: Boolean
}
//FIXME:member唯一性
@deprecated
trait CurClusterStates extends AkkaSystemable with IClusterStates {
  protected def listenName: String
  var upMembers = Set[Member]() //Up状态的机器  
  var downMembers = Set[Member]() //已经被removed的机器
  var exitedMembers = Set[Member]() //提出集群的机器，集群访问无效但是Rmi和远程akka可以访问
  var unreachableMembers = Set[Member]() //心跳信号访问不到的机器，可能因为网络不稳而暂时访问不到
  var roleLeaderMemberMap = Map[String, Option[Address]]() //哪些角色
  var leaderMember: Option[Address] = None
  var nodeMemberMetrics: Set[NodeMetrics] = Set.empty[NodeMetrics]
  var seenByMembers: Set[Address] = Set.empty[Address] //被哪几台监视
  var init = false
  private val my = this

  val listener = system.actorOf(Props(new ClusterListener {
    protected val listen = Seq(classOf[ClusterDomainEvent])
    def receive = {
      case CurrentClusterState(members, unreachable, seenBy, leader, roleLeaderMap) =>
        upMembers = members
        unreachableMembers = unreachable
        seenByMembers = seenBy
        leaderMember = leader
        roleLeaderMemberMap = roleLeaderMap
        init = true
      case MemberUp(member) =>
        upMembers = upMembers + member
        downMembers = downMembers - member
        unreachableMembers = unreachableMembers - member
        exitedMembers = exitedMembers - member

      case UnreachableMember(member) =>
        upMembers = upMembers - member
        downMembers = downMembers - member
        unreachableMembers = unreachableMembers + member
        exitedMembers = exitedMembers - member

      case MemberExited(member) =>
        upMembers = upMembers - member
        downMembers = downMembers - member
        unreachableMembers = unreachableMembers - member
        exitedMembers = exitedMembers + member

      case MemberRemoved(member, previousStatus) =>
        upMembers = upMembers - member
        downMembers = downMembers + member
        unreachableMembers = unreachableMembers - member
        exitedMembers = exitedMembers - member

      case LeaderChanged(leader) =>
        leaderMember = leader

      case RoleLeaderChanged(role, leader) =>
        roleLeaderMemberMap = roleLeaderMemberMap + (role -> leader)

      case ClusterMetricsChanged(nodeMetrics) =>
        nodeMemberMetrics = nodeMetrics

      case _ => // ignore
    }
  }), listenName)
}